﻿//  -------------------- iSharePoint -------------------- //
// 
//  Company:	IT Complex, LLC
//  Project:	Smart.Common
//  File name:	MetaScope.cs
//  Developer:	Solomatov Igor
//  Created:	15.04.2012
// 
//  -------------------- iSharePoint -------------------- //

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace Smart.Common
{
	/// <summary>
	/// Store metadata about Scope
	/// </summary>
	[DebuggerDisplay("MetaScope Name={Name} Title={Title}")]
	public abstract class MetaScope
	{
		/// <summary>
		/// Scope ID
		/// </summary>
		public Guid ID { get; set; }

		/// <summary>
		/// Scope Name
		/// </summary>
		public string Name { get; set; }

		/// <summary>
		/// Scope Title
		/// </summary>
		public string Title { get; set; }

		/// <summary>
		/// All lists ID
		/// </summary>
		public Dictionary<string, Guid> ListIDs { get; set; }

		/// <summary>
		/// All lists metadata
		/// </summary>
		public Dictionary<Guid, MetaList> Lists { get; set; }

		/// <summary>
		/// Store metadata about Scope
		/// </summary>
		protected MetaScope(Guid id, string name, string title)
		{
			ID = id;
			Name = name;
			Title = title;

			ListIDs = new Dictionary<string, Guid>(StringComparer.OrdinalIgnoreCase);
			Lists = new Dictionary<Guid, MetaList>();
		}

		/// <summary>
		/// Fill cache info
		/// </summary>
		public abstract void LoadLists(object source, ICollection<string> includeLists, IDictionary<string, FacadeMappingInfo> mappingInfo);

		/// <summary>
		/// Filter metadata
		/// </summary>
		public virtual void FilterLists(IEnumerable<string> includeLists)
		{
			if (includeLists == null)
				throw new ArgumentNullException();

			var dLists =
				includeLists
					.Select(listId => ListIDs.SafeGet(listId, Guid.Empty))
					.Where(listId => !listId.IsEmpty())
					.ToDictionary(listId => listId, listId => true);

			var RemoveKeys =
				ListIDs
					.Where(kvp => !dLists.ContainsKey(kvp.Value))
					.Select(kvp => kvp.Key)
					.ToArray();

			foreach (var kvp in dLists)
			{
				Lists.Remove(kvp.Key);
			}

			foreach (var key in RemoveKeys)
			{
				ListIDs.Remove(key);
			}
		}

		/// <summary>
		/// Return MetaList by Id
		/// </summary>
		public virtual MetaList List(Guid id)
		{
			var res = (id == Guid.Empty ? null : Lists.SafeGet(id));

			if (res == null)
			{
				H.LT("MetaList:List.2 Exception: list '{0}' not found at '{1}'!", id, Title);
			}

			return res;
		}

		/// <summary>
		/// Return MetaList by TitleOrUrl
		/// </summary>
		public virtual MetaList List(string titleOrUrl)
		{
			var id = ListIDs.SafeGet(titleOrUrl);

			var res = (id == Guid.Empty ? null : Lists.SafeGet(id));

			if (res == null)
			{
				H.LT("MetaList:List.3 Exception: list '{0}' not found at '{1}'!", titleOrUrl, Title);
			}

			return res;
		}

		/// <summary>
		/// Return list id by ListTitleOrUrl
		/// </summary>
		public virtual Guid ListId(string listTitleOrUrl)
		{
			var ml = List(listTitleOrUrl);

			return ml == null ? Guid.Empty : ml.ID;
		}

		/// <summary>
		/// Return list field name by ListTitleOrUrl and FieldTitleOrName
		/// </summary>
		public virtual string FieldName(string listTitleOrUrl, string fieldTitleOrName)
		{
			var ml = this.List(listTitleOrUrl);

			return ml == null ? "_ERROR_LIST_NOT_FOUND_" : ml.FieldName(fieldTitleOrName);
		}

		/// <summary>
		/// Return list field name by ListTitleOrUrl and FieldTitleOrName
		/// </summary>
		public virtual string FieldName(string listTitleOrUrl, Guid id)
		{
			var ml = this.List(listTitleOrUrl);

			return ml == null ? "_ERROR_LIST_NOT_FOUND_" : ml.FieldName(id);
		}
	}
}